#include <stdio.h>
#include <stdlib.h>
#include "ListaAsoc.h"
#include "cr.h"
#include "cw.h"
#include "assert.h"


struct sListaAsoc{
	Cinta cinta;
};

ListaAsoc la_empty(void){
	ListaAsoc lista = (ListaAsoc)calloc(1,sizeof(struct sListaAsoc));
	aList listavacia = aList_vacia();
	lista->cinta = cinta_create(listavacia); 
	cinta_arr(lista->cinta); 
	return lista;
}

bool la_exists(ListaAsoc lista, key clave){
	bool b = FALSE;
	
	assert(lista != NULL);
	cinta_arr(lista->cinta);
	while (!b && !cinta_fin(lista->cinta)){ 
		b = key_eq(clave,tuple_fst(cinta_elec(lista->cinta))); 
		cinta_av(lista->cinta);
		}
	return b;
}

void la_add (ListaAsoc lista, key clave, data dato){
	tuple tupla = tuple_fromKeyData(clave,dato);
	
	assert(lista!=NULL);
	cinta_ins(lista->cinta,tupla);
	tupla = tuple_destroy(tupla);
}

data la_search (ListaAsoc lista, key clave){
	assert(lista!=NULL);
	cinta_arr(lista->cinta);
	while (!key_eq(clave,tuple_fst(cinta_elec(lista->cinta))) && !cinta_fin(lista->cinta)) 
		cinta_av(lista->cinta);
	return (tuple_snd(cinta_elec(lista->cinta)));
}

void la_del (ListaAsoc lista, key clave){
	assert(lista!=NULL);
	cinta_arr(lista->cinta);
	while (!key_eq(clave,tuple_fst(cinta_elec(lista->cinta))) && !cinta_fin(lista->cinta)){
		cinta_av(lista->cinta);
		}
	cinta_del(lista->cinta);
}

int la_length (ListaAsoc lista){
	int i = 0;
	assert(lista!=NULL);
	cinta_arr(lista->cinta);
	while (!cinta_fin(lista->cinta)){
		cinta_av(lista->cinta);
		i = i+1;
		} 	
	return i;
}

void la_pprint (ListaAsoc lista){
	char * p = NULL;
	char * q = NULL;
	assert(lista!=NULL);
	cinta_arr(lista->cinta);
	while (!cinta_fin(lista->cinta)){
		p = (char*)calloc(key_lenght(tuple_fst(cinta_elec(lista->cinta)))+1,sizeof(char));
		key_toString(tuple_fst(cinta_elec(lista->cinta)),p);
		q = data_toString(tuple_snd(cinta_elec(lista->cinta)));
		printf("\n%s: %s \n \n",p,q);
		free(p);
		p = NULL;
		free(q);
		q = NULL;
		cinta_av(lista->cinta);
		}
}
 
ListaAsoc la_destroy (ListaAsoc lista){
	assert(lista!=NULL);
	aList_destroy(cinta_destroy(lista->cinta)); 
	free(lista);
	lista = NULL;
	return lista;
}

ListaAsoc la_fromFile(char *nomfile){
	ListaAsoc lista = la_empty();
	tuple e;
	cr c;

	assert(nomfile!=NULL);
	c = cr_create(nomfile);

	cr_arr(c);
	while (!cr_fin(c)){
		e = cr_elec(c);
		cinta_ins(lista->cinta,e);
		e = tuple_destroy(e);
		cr_av(c);
	}
	cr_destroy(c);
	return lista;
}

void la_toFile(char *nomfile, ListaAsoc la) {
	tuple e;
	cw c;

	assert(la!=NULL);
	c = cw_create(nomfile);

	cw_arr(c);
	cinta_arr(la->cinta);
	while(!cinta_fin(la->cinta)){
		e = cinta_elec(la->cinta);
		cinta_av(la->cinta);
		cw_ins(c,e);
	}
	cw_destroy(c);
}
